package com.jinmdz.fmis.api.admin.service;

import com.jinmdz.fmis.api.admin.model.servicebusiness.ServiceBusinessCodeData;
import com.jinmdz.fmis.api.admin.model.servicebusiness.ServiceBusinessDataSaveData;
import com.jinmdz.fmis.api.api.model.common.IdVersionData;
import com.jinmdz.fmis.api.base.BaseService;
import com.jinmdz.fmis.api.model.config.dictionary.OperationLogCode;
import com.jinmdz.fmis.api.model.system.UserItem;
import com.jinmdz.fmis.api.wrapper.OperationWrapper;
import com.jinmdz.fmis.common.ext.StringBuilderExt;
import com.jinmdz.fmis.common.util.DataUtil;
import com.jinmdz.fmis.core.base.BaseResult;
import com.jinmdz.fmis.core.exception.ActionException;
import com.jinmdz.fmis.core.util.JacksonUtil;
import com.jinmdz.fmis.dao.admin.dao.GoodsServiceDao;
import com.jinmdz.fmis.dao.admin.dao.ServiceBusinessDao;
import com.jinmdz.fmis.dao.admin.model.goodsservice.GoodsServiceEditItem;
import com.jinmdz.fmis.dao.admin.model.servicebusiness.ServiceBusinessDataListItem;
import com.jinmdz.fmis.mapper.entity.ServiceBusinessItemEntity;
import com.jinmdz.fmis.mapper.mapper.ServiceBusinessItemMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;

/**
 * 业务模块使用物品服务关联关系设置
 *
 * @author GuanKui
 * @date 2020/3/16 13:48
 */
@Service("serviceBusinessService")
public class ServiceBusinessService extends BaseService {

    @Resource
    private ServiceBusinessDao serviceBusinessDao;

    @Resource
    private ServiceBusinessItemMapper serviceBusinessItemMapper;

    @Resource
    private OperationWrapper operationWrapper;

    @Resource
    private OperationLogCode operationLogCode;

    @Resource
    private GoodsServiceDao goodsServiceDao;

    /**
     * 根据业务编码加载业务模块下的数据项列表
     *
     * @param data 业务类型数据
     * @return
     * @author GuanKui
     * @date 2020/3/12  11:30
     */
    public BaseResult<ArrayList<ServiceBusinessDataListItem>> loadServiceBusinessDataListWithCode(ServiceBusinessCodeData data) {
        ArrayList<ServiceBusinessDataListItem> loadItems = serviceBusinessDao.listServiceBusinessDataListByBusinessType(data.getBusinessType());
        return successList(loadItems);
    }

    /**
     * 保存业务、费用关联数据信息
     *
     * @param userItem 当前账号
     * @param data     关联数据
     * @return
     * @author GuanKui
     * @date 2020/3/16  13:54
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult saveServiceBusinessData(UserItem userItem, ArrayList<ServiceBusinessDataSaveData> data) throws ActionException {
        // 判断关联数据是否有效
        if (DataUtil.invalid(data)) {
            return failure("请选择关联物品服务");
        }

        // 得到第一个业务类型
        String businessType = data.get(0).getBusinessType();

        // 记录主键
        ArrayList<Integer> idList = new ArrayList<>();
        for (ServiceBusinessDataSaveData saveData : data) {
            if (!idList.contains(saveData.getServiceItemId())) {
                idList.add(saveData.getServiceItemId());
            }
        }
        // 去重
        idList = DataUtil.repeatArrayList(idList);

        // 遍历关联数据
        for (Integer serviceItemId : idList) {
            // 验证是否存在重复
            Integer serviceBusinessId = serviceBusinessDao.getServiceBusinessIdByServiceItemId(businessType, serviceItemId);
            if (DataUtil.valid(serviceBusinessId)) {
                // 当已存在关联信息时，继续追加其他的信息
                continue;
            }

            GoodsServiceEditItem loadItem = goodsServiceDao.getGoodsServiceEditById(serviceItemId);
            if (DataUtil.isNull(loadItem) || DataUtil.isNull(loadItem.getId(), loadItem.getVersion())) {
                // 不存在的关联信息，继续追加其的信息
                continue;
            }

            // 创建关联实体
            ServiceBusinessItemEntity entity = getEntity(userItem, ServiceBusinessItemEntity.class);
            // 覆盖数据
            entity.setBusinessType(businessType)
                    .setServiceItemId(serviceItemId);

            // 执行插入数据
            serviceBusinessItemMapper.insertServiceBusinessItem(entity);
            // 判断插入结果
            if (DataUtil.invalid(entity.getId())) {
                throw exception("保存关联失败");
            }
        }

        // 添加日志
        saveServiceBusinessDataLog(userItem, data);

        return success("保存完成");
    }

    /**
     * 添加新增记录:保存业务、费用关联数据信息
     *
     * @param userItem 当前帐号
     * @param data     请求数据
     * @return
     * @author GuanKui
     * @date 2020/3/16  15:21
     */
    private void saveServiceBusinessDataLog(UserItem userItem, ArrayList<ServiceBusinessDataSaveData> data) throws ActionException {
        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("保存业务、费用关联数据信息，操作人员[{0}]", userItem.getFullName());
        // 添加日志
        operationWrapper.operationLog(userItem, operationLogCode.getInsert(), builder.toString(), JacksonUtil.obj2Json(data), null, null);
    }

    /**
     * 删除业务、费用关联数据关联信息
     *
     * @param userItem 当前账号
     * @param data     主键和数据版本
     * @return
     * @author GuanKui
     * @date 2020/3/16  13:59
     */
    @Transactional(rollbackFor = Exception.class)
    public BaseResult deleteServiceBusinessDataWithId(UserItem userItem, ArrayList<IdVersionData> data) throws ActionException {
        // 判断删除主键集合是否存在
        if (DataUtil.invalid(data)) {
            throw exception("不存在要删除的关联信息");
        }

        // 验证主键是否重复
        if (data.size() != getRepeatIdSize(data)) {
            throw exception("关联主键存在重复");
        }

        // 遍历查询进行删除
        for (IdVersionData idData : data) {
            // 通过主键查询数据版本号
            Long version = serviceBusinessDao.getServiceBusinessVersionById(idData.getId());
            if (DataUtil.isNull(version)) {
                throw exception("主键错误,不存在此业务关联服务信息");
            }

            // 验证服务类型信息版本
            if (!DataUtil.equals(version, idData.getVersion())) {
                throw exception(versionError("业务关联服务信息"));
            }

            // 删除关联信息
            serviceBusinessItemMapper.deletedForServiceBusinessItem(idData.getId(), userItem.getId(), idData.getVersion());
        }

        // 添加曹若日志
        deleteServiceBusinessDataLog(userItem, operationLogCode.getDelete(), data);
        return success("删除完成");
    }

    /**
     * 添加删除记录:删除业务、费用关联数据关联信息
     *
     * @param userItem    当前帐号
     * @param logTypeCode 操作日志值
     * @param data        请求数据
     * @return
     * @author GuanKui
     * @date 2020/3/16  15:21
     */
    private void deleteServiceBusinessDataLog(UserItem userItem, Integer logTypeCode, ArrayList<IdVersionData> data) throws ActionException {
        // 操作日志字符串
        StringBuilderExt builder = new StringBuilderExt();
        builder.format("删除业务、费用关联数据关联信息，操作人员[{0}]", userItem.getFullName());
        // 添加日志
        operationWrapper.operationLog(userItem, operationLogCode.getDelete(), builder.toString(), null, null, null);
    }
}